package com.jplus.framework.db;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 数据源工厂
 *
 * @author huangyong
 * @author Yuanqy
 */
public abstract class DataSourceFactory {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	private JdbcTemplate jdbcTemplate;
	/**
	 * 定义一个局部线程变量（使每个线程都拥有自己的连接）
	 */
	private final ThreadLocal<Connection> connection = new ThreadLocal<Connection>();

	/**
	 * 获取数据源
	 *
	 * @return 数据源
	 */
	public abstract DataSource getDataSource();

	public synchronized Connection getConnection() {
		Connection conn;
		try {
			conn = connection.get();
			if (conn == null || conn.isClosed()) {
				conn = getDataSource().getConnection();
				if (conn != null) {
					connection.set(conn);
				}
			}
		} catch (SQLException e) {
			logger.error("获取数据库连接出错！", e);
			throw new RuntimeException(e);
		}
		return conn;
	}

	/**
	 * 开启事务
	 */
	public void beginTransaction() {
		Connection conn = getConnection();
		if (conn != null) {
			try {
				conn.setAutoCommit(false);
			} catch (SQLException e) {
				logger.error("开启事务出错！", e);
				throw new RuntimeException(e);
			} finally {
				connection.set(conn);
			}
		}
	}

	/**
	 * 提交事务
	 */
	public void commitTransaction() {
		Connection conn = getConnection();
		if (conn != null) {
			try {
				conn.commit();
				conn.close();
			} catch (SQLException e) {
				logger.error("提交事务出错！", e);
				throw new RuntimeException(e);
			} finally {
				connection.remove();
			}
		}
	}

	/**
	 * 回滚事务
	 */
	public void rollbackTransaction() {
		Connection conn = getConnection();
		if (conn != null) {
			try {
				conn.rollback();
				conn.close();
			} catch (SQLException e) {
				logger.error("回滚事务出错！", e);
				throw new RuntimeException(e);
			} finally {
				connection.remove();
			}
		}
	}

	/**
	 * 获取JdbcTemplate
	 */
	public synchronized JdbcTemplate getJdbcTemplate() {
		if (jdbcTemplate == null)
			jdbcTemplate = new JdbcTemplate();
		return jdbcTemplate;
	}
}
